import datetime

from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin
from extensions.paginations import LimitedPagination, InfinitePagination
from rest_framework.filters import SearchFilter, OrderingFilter
from django_filters.rest_framework import DjangoFilterBackend
from django.db.models.deletion import ProtectedError
from rest_framework.viewsets import GenericViewSet
from extensions.exceptions import ValidationError
from django.http.response import HttpResponse
import openpyxl
from openpyxl import Workbook, load_workbook
from rest_framework.viewsets import ViewSet
from openpyxl.utils import get_column_letter


class FunctionViewSet(ViewSet):
    """功能视图"""

    @property
    def team(self):
        return self.request.user.team

    @property
    def user(self):
        return self.request.user

    @property
    def context(self):
        print("FunctionViewSet")
        return {'request': self.request, 'format': self.format_kwarg, 'view': self}


class BaseViewSet(GenericViewSet):
    pagination_class = LimitedPagination
    filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
    ordering_fields = ['id']
    ordering = ['-id']
    select_related_fields = []
    prefetch_related_fields = []

    @property
    def team(self):
        return self.request.user.team

    @property
    def user(self):
        return self.request.user

    @property
    def context(self):
        return self.get_serializer_context()

    def get_queryset(self):
        # queryset = super().get_queryset().filter(team=self.team)
        queryset = super().get_queryset()
        queryset = queryset.select_related(*self.select_related_fields)
        queryset = queryset.prefetch_related(*self.prefetch_related_fields)
        return queryset
    
    
class SafeDestroyMixin(DestroyModelMixin):
    
    def perform_destroy(self, instance):
        try:
            instance.delete()
        except ProtectedError:
            raise ValidationError('已被数据引用, 无法删除')


class ModelViewSet(BaseViewSet, ListModelMixin, CreateModelMixin,
                   RetrieveModelMixin, UpdateModelMixin, SafeDestroyMixin):
    """模型视图"""


class PersonalViewSet(BaseViewSet):
    """个人试图"""

    def get_queryset(self):
        return super().get_queryset().filter(creator=self.user)


class LimitedOptionViewSet(BaseViewSet, ListModelMixin):
    """有限选项视图"""


class InfiniteOptionViewSet(BaseViewSet, ListModelMixin):
    """无限选项视图"""

    pagination_class = InfinitePagination


class ReadOnlyMixin(RetrieveModelMixin, ListModelMixin):
    """只读"""


class ExportMixin:
    """导出"""

    def get_export_response(self, serializer_class, data=None):
        """获取导出Excel文件响应

        Args:
            serializer_class (BaseSerializer): 序列化类
            data (list): 数据

            serializer (BaseSerializer): 序列化器
            field_items (List): 字段属性

        Returns:
            HttpResponse: 文件响应
        """

        workbook = Workbook()
        work_sheet = workbook.active

        if data:
            results = data
        else:
            queryset = self.filter_queryset(self.get_queryset())
            serializer = serializer_class(instance=queryset, many=True)
            results = serializer.data
        field_items = serializer_class().get_fields().items()

        # 创建表头
        for index, (field_name, field_class) in enumerate(field_items, start=1):
            work_sheet.cell(row=1, column=index, value=field_class.label)

        # 填充数据
        for row, item in enumerate(results, start=2):
            for column, (field_name, field_class) in enumerate(field_items, start=1):
                work_sheet.cell(row=row, column=column, value=item.get(field_name, ''))

        response = HttpResponse(content_type='application/vnd.ms-excel')
        response['Content-Disposition'] = 'attachment;filename=data.xlsx'
        workbook.save(response)

        return response


class ImportMixin:
    """导入"""

    # def get_template_response(self, serializer_class):
    #     """获取Excel模板响应
    #
    #     Args:
    #         serializer_class (BaseSerializer): 序列化类
    #
    #     Returns:
    #         HttpResponse: 文件响应
    #     """
    #
    #     workbook = Workbook()
    #     work_sheet = workbook.active
    #
    #     # 创建表头
    #     field_items = serializer_class().get_fields().items()
    #     for index, (_, field_class) in enumerate(field_items, start=1):
    #         work_sheet.cell(row=1, column=index, value=field_class.label)
    #
    #     response = HttpResponse(content_type='application/vnd.ms-excel')
    #     response['Content-Disposition'] = 'attachment;filename=data.xlsx'
    #     workbook.save(response)
    #
    #     return response

    from openpyxl.utils import get_column_letter

    def get_template_response(self, serializer_class,title=""):
        """获取Excel模板响应

        Args:
            serializer_class (BaseSerializer): 序列化类

        Returns:
            HttpResponse: 文件响应
        """

        workbook = openpyxl.Workbook()
        work_sheet = workbook.active

        # 设置工作表名称
        work_sheet.title = title

        # 设置标题
        work_sheet.merge_cells(start_row=1, start_column=1, end_row=1, end_column=len(serializer_class().get_fields()))
        title_cell = work_sheet.cell(row=1, column=1)
        title_cell.value = title
        title_cell.alignment = openpyxl.styles.Alignment(horizontal='left')

        # 设置标题字体样式
        title_font = openpyxl.styles.Font(bold=True, size=14)
        title_cell.font = title_font
        title_cell.alignment = openpyxl.styles.Alignment(horizontal='center')  # 将标题居中

        # 创建表头
        field_items = serializer_class().get_fields().items()
        max_widths = {}
        for index, (_, field_class) in enumerate(field_items, start=1):
            column_letter = get_column_letter(index)
            work_sheet.cell(row=2, column=index, value=field_class.label)

            # 记录每列的最大宽度
            current_width = len(field_class.label)
            max_widths[column_letter] = max(max_widths.get(column_letter, 0), current_width)

            # 设置单元格的对齐方式为居中
            cell = work_sheet.cell(row=2, column=index)
            cell.alignment = openpyxl.styles.Alignment(horizontal='center')

        # 根据最大宽度设置列宽
        for column_letter, max_width in max_widths.items():
            adjusted_width = max(10, (max_width * 2) + 1)
            work_sheet.column_dimensions[column_letter].width = adjusted_width

            # 为第 2 行到第 10 行的单元格添加边框
            border = openpyxl.styles.Border(
                left=openpyxl.styles.Side(style='thin'),
                right=openpyxl.styles.Side(style='thin'),
                top=openpyxl.styles.Side(style='thin'),
                bottom=openpyxl.styles.Side(style='thin')
            )

            num_columns = len(serializer_class().get_fields().items())
            for row in range(2, 4):  # 从第 2 行到第 10 行
                for col in range(1, num_columns + 1):
                    cell = work_sheet.cell(row=row, column=col)
                    cell.border = border

        response = HttpResponse(content_type='application/vnd.ms-excel')
        response['Content-Disposition'] = 'attachment;filename=data.xlsx'
        workbook.save(response)

        return response

    # def load_data(self, file, serializer_class):
    #     workbook = load_workbook(file)
    #     work_sheet = workbook.active
    #     field_items = serializer_class().get_fields().items()
    #
    #     for column, (field_name, field_class) in enumerate(field_items):
    #         if work_sheet[1][column].value != field_class.label:
    #             raise ValidationError('格式错误')
    #
    #     data = []
    #     for row in range(2, work_sheet.max_row + 1):
    #         instance_item = {}
    #         for column, (field_name, field_class) in enumerate(field_items):
    #             if work_sheet[row][column].value is not None:
    #                 instance_item[field_name] = work_sheet[row][column].value
    #         else:
    #             data.append(instance_item)
    #
    #     serializer = serializer_class(data=data, many=True, context=self.context)
    #     return serializer

    def load_data(self, file, serializer_class):
        workbook = load_workbook(file)
        work_sheet = workbook.active
        field_items = serializer_class().get_fields().items()

        # 表头位于第 2 行
        for column, (field_name, field_class) in enumerate(field_items):
            if work_sheet.cell(row=2, column=column + 1).value != field_class.label:
                raise ValidationError('格式错误')
        data = []
        # 数据从第 3 行开始
        for row in range(3, work_sheet.max_row + 1):
            instance_item = {}
            for column, (field_name, field_class) in enumerate(field_items):
                if work_sheet.cell(row=row, column=column + 1).value is not None:
                   instance_item[field_name] = work_sheet.cell(row=row, column=column + 1).value
            else:
                if instance_item:
                    data.append(instance_item)
        print(data)

        serializer = serializer_class(data=data, many=True, context=self.context)
        return serializer


__all__ = [
    'FunctionViewSet', 'BaseViewSet', 'ModelViewSet', 'PersonalViewSet',
    'LimitedOptionViewSet', 'InfiniteOptionViewSet',
    'ReadOnlyMixin', 'SafeDestroyMixin', 'ExportMixin', 'ImportMixin',
    'ListModelMixin', 'CreateModelMixin', 'RetrieveModelMixin', 'UpdateModelMixin', 'DestroyModelMixin',
    'DjangoFilterBackend', 'SearchFilter', 'OrderingFilter',
]
